package cn.com.vs.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

import cn.com.vs.model.CreateSportsDataStaus;
import cn.com.vs.service.domain.Activity;
import cn.com.vs.service.domain.ActivityBrief;
import cn.com.vs.service.domain.ApplicationBrief;
import cn.com.vs.service.domain.Registration;
import cn.com.vs.service.domain.SportsData;
import cn.com.vs.service.domain.SportsDataDetail;
import cn.com.vs.service.domain.SportsDataRecordInfo;
import cn.com.vs.service.mapper.ActivityMapper;
import cn.com.vs.service.domain.RecordData;
import cn.com.vs.utils.DBUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

public class ActivityService {
	private static Logger logger = Logger.getLogger(ActivityService.class);
	private ActivityService(){
	};
	private static ActivityService inst = new ActivityService();

	public static ActivityService getInstance(){
		return inst;
	}

	public boolean init(){
		return true;
	}

	public enum RetCode{
		OK("成功",0),
		INSERT_FAILD("生成数据失败",1),
		GROUP_FAILD("创建聊天组数据时失败",2),
		SAVE_MAPDATA_FAILD("保存位置信息时失败",3),
		NOT_EXIST("目标不存在",4),
		PUB_FAILD("活动已发布或已过期,发布失败",5),
		EXPIRED("活动已过期",6),
		MAXLIMIT("活动已满员",7),
		REGISTEDALREADY("已报名，无需重复报名",8),
		TRACKDATAEXIST("数据已存在",9),
		EXCEPTION("处理异常",100);
		private String desc;
		private int    code;

		RetCode(String desc,int code){
			this.desc = desc;
			this.code = code;
		}
		public String getDesc(){
			return desc;
		}
		public int getCode(){
			return code;
		}
	}

	public RetCode createActivity(Integer userid,String account,JSONObject activity)
	{
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			activity.put("authorid", userid);
			int status = activity.getIntValue("status");
			if( status==1 && activity.containsKey("enableChat") && activity.getBooleanValue("enableChat") ){
				Integer maxUser = activity.getInteger("maxMembers");
				if( maxUser == null || maxUser == -1 ){
					maxUser = 5000;
				}
				
				Integer chatGroupId = UserService.getInstance().createGroup(userid, account, activity.getString("title"),
						activity.getString("digest"), true, maxUser, false, 3, null, activity.getString("address"), activity.getString("location"), null, null);
				if( chatGroupId == null ){
					return RetCode.GROUP_FAILD;
				}
				activity.put("chatgroupid", chatGroupId);
			}
			String location = activity.getString("location");
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			
			Map<String,Object> params = (Map<String,Object>)activity;
			int ret =  mapper.createActivity(params);
			if( ret > 0 ){
				if( status == 1 ){
					Integer activityID = (Integer)params.get("id");
					int locid = CloudMapService.getInstance().createAnnotation(activity.getString("title"),
							activity.getString("address"),
							location, activity.getIntValue("type"), activityID,activity.getString("digest"),
							activity.getInteger("openTime"), activity.getInteger("closeTime"));
					if( locid <= 0 ){
						return RetCode.SAVE_MAPDATA_FAILD;
					}
					params.clear();
					params.put("id", activityID );
					params.put("locationid", locid);
					mapper.updateActivity(params);
					//把自己也算作报名一员
					registration(activityID,userid,1,null);
				}
				params.put("status", status);
				return RetCode.OK;
			}
			return RetCode.INSERT_FAILD;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}
	
	public RetCode updateActivity(Integer userid,String account,JSONObject activity)
	{
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			
			int status = activity.getIntValue("status");
			if( status==1 && activity.containsKey("enableChat") && activity.getBooleanValue("enableChat") ){
				Integer maxUser = activity.getInteger("maxMembers");
				if( maxUser == null || maxUser == -1 ){
					maxUser = 5000;
				}
				
				Integer chatGroupId = UserService.getInstance().createGroup(userid, account, activity.getString("title"),
						activity.getString("digest"), true, maxUser, false, 3, null, activity.getString("address"), activity.getString("location"), null, null);
				if( chatGroupId == null ){
					return RetCode.GROUP_FAILD;
				}
				activity.put("chatgroupid", chatGroupId);
			}
			
			String location = activity.getString("location");
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );

			Map<String,Object> params = (Map<String,Object>)activity;
			if( status == 1 ){
				Integer activityID = (Integer)params.get("id");
				int locid = CloudMapService.getInstance().createAnnotation(activity.getString("title"),
						activity.getString("address"),
						location, activity.getIntValue("type"), activityID,activity.getString("digest"),
						activity.getInteger("openTime"), activity.getInteger("closeTime"));
				if( locid <= 0 ){
					return RetCode.SAVE_MAPDATA_FAILD;
				}
				params.put("locationid", locid);
				//把自己也算作报名一员
				registration(activityID,userid,1,null);
			}
			mapper.updateActivity(params);
			return RetCode.OK;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}

	public RetCode deleteActivity(int activityID)
	{
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Activity act = mapper.getActivity(activityID);
			if( act == null ){
				return RetCode.NOT_EXIST;
			}
			int locid = act.getLocationid();
			if( locid >0 ){
				CloudMapService.getInstance().deleteAnnotation(locid);
			}
			int gid = act.getChatgroupid();
			if( gid > 0 ){
				UserService.getInstance().deleteGroup(act.getAuthorid(), gid);
			}
			int ret = mapper.deleteActivity(activityID);
			System.out.println("delete activity:"+activityID+" ret="+ret);
			return RetCode.OK;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}

	public Activity getActivity(int activityID){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			return mapper.getActivity(activityID);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}

	public List<Activity> getMyActivites(Integer userid,Integer from,Integer limit)
	{
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getMyActivities(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}

	public List<Activity> getActivites(Integer userid,Integer from,Integer limit)
	{
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getActivities(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}

	public List<Activity> searchLocalActivites(Integer userid,String keywords,String city,Integer type,Integer from,Integer limit)
	{
		SqlSession session = null;
		try{
			List<ActivityBrief> res = CloudMapService.getInstance().getLocalAnnotationBrief(keywords, city, type);
			if( res == null )
				return null;
			if( res.isEmpty() )
				return Collections.emptyList();
			
			List<Integer> ids = new ArrayList<Integer>();
			for(ActivityBrief brief:res ){
				ids.add( brief.getId() );
			}
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("ids", ids);
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getActivitiesInRange(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}

	public List<Activity> searchAroundActivites(Integer userid,String center,
			Integer radius,String keywords,Integer type,Integer from,Integer limit)	{
		SqlSession session = null;
		try{
			List<ActivityBrief> res = CloudMapService.getInstance().getAroundAnnotationBrief(center, radius==null?5000:radius, keywords,type);
			if( res == null )
				return null;
			if( res.isEmpty() )
				return Collections.emptyList();
			List<Integer> ids = new ArrayList<Integer>();
			Map<Integer,Integer> distanceMap = new HashMap<Integer,Integer>();
			for(ActivityBrief brief:res ){
				ids.add( brief.getId() );
				distanceMap.put(brief.getId(), brief.getDistance() );
			}
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("ids", ids);
			params.put("from", from);
			params.put("limit", limit);
			List<Activity> result = mapper.getActivitiesInRange(params);
			if( result != null ){
				for(Activity act:result){
					act.setDistance( distanceMap.get( act.getId() ) ) ;
				}
			}
			return result;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public List<Activity> searchRegionActivites(Integer userid,String region
			,String keywords,Integer type,Integer from,Integer limit)	{
		SqlSession session = null;
		try{
			List<ActivityBrief> res = CloudMapService.getInstance().getRegionAnnotationBrief(keywords, region, type);
			if( res == null )
				return null;
			if( res.isEmpty() )
				return Collections.emptyList();
			List<Integer> ids = new ArrayList<Integer>();
			Map<Integer,Integer> distanceMap = new HashMap<Integer,Integer>();
			for(ActivityBrief brief:res ){
				ids.add( brief.getId() );
				distanceMap.put(brief.getId(), brief.getDistance() );
			}
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("ids", ids);
			params.put("from", from);
			params.put("limit", limit);
			List<Activity> result = mapper.getActivitiesInRange(params);
			if( result != null ){
				for(Activity act:result){
					act.setDistance( distanceMap.get( act.getId() ) ) ;
				}
			}
			return result;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public RetCode registration(Integer activityid,Integer userid,String msg){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Activity act = mapper.getActivity(activityid);
			if( act == null ){
				return RetCode.NOT_EXIST;
			}
			if( act.getStatus() == 2 ){
				return RetCode.EXPIRED;
			}
			if( act.getMaxMembers() > 0 && act.getRegistrations() >= act.getMaxMembers() ){
				return RetCode.MAXLIMIT;
			}
			int status = 1;
			if( act.getNeedConfirm() > 0 ){
				status = 0;
			}
			return registration(activityid,userid,status,msg);
		}catch(Exception e){
			if( e.getCause() instanceof MySQLIntegrityConstraintViolationException ){
				return RetCode.REGISTEDALREADY;
			}
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}
	
	public RetCode registration(Integer activityid,Integer userid,Integer status,String msg){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("activityid", activityid);
			params.put("userid", userid);
			params.put("status", status);
			params.put("msg", msg);
			int ret = mapper.registration(params);
			return ret>0?RetCode.OK:RetCode.EXCEPTION;
		}catch(Exception e){
			if( e.getCause() instanceof MySQLIntegrityConstraintViolationException ){
				return RetCode.REGISTEDALREADY;
			}
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}

	public List<Registration> getRegistrations(Integer activityid,Integer status,Integer from ,Integer limit){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("activityid", activityid);
			if( status != null ){
				params.put("status", status);
			}
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getRegistrations(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public boolean confirmMemberApplication(Integer activityid,Integer regUserid){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("activityid", activityid);
			params.put("userid", regUserid);
			int ret = mapper.confirmRegistration(params);
			return ret>0;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return false;
	}
	
	public boolean cancelApplication(Integer activityid,Integer userid){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("activityid", activityid);
			params.put("userid", userid);
			int ret = mapper.cancelRegistration(params);
			return ret>0;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return false;
	}
	
	public List<ApplicationBrief> getActivityHistory(Integer userid,Integer from ,Integer limit){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getMyRegistrations(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public List<Activity> getJoinedActivity(Integer userid,Integer from ,Integer limit){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("from", from);
			params.put("limit", limit);
			return mapper.getMyRegistrationsDetail(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public RetCode createSportsData(Integer userid,String type ,String matchName,String memo,Long startTime,
			Long duration,Long elapsedduration,String timezone,Double distance,Integer calories,String device,String metrics,
			int k1bests, int k5bests, int k10bests, int halfbests, int marathonbests, String uuid, CreateSportsDataStaus st){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("type", type);
			params.put("matchname", matchName);
			params.put("memo", memo);
			params.put("startTime", startTime);
			params.put("duration", duration);
			params.put("elapsedduration", elapsedduration);
			params.put("timezone", timezone);
			params.put("distance", distance);
			params.put("calories", calories);
			params.put("metrics", metrics);
			params.put("device", device);
			params.put("uuid", uuid);
			int ret = mapper.createSportsData(params);
			
			if(ret > 0) {
				st.setId((Long)params.get("id"));
				SportsData sportsData = mapper.getSportsDataById(st.getId());
				if(sportsData != null) {
					st.setCv(sportsData.getCv());
				}
				
				SportsDataRecordInfo sportsDataRecordInfo = getSportsDataRecordInfo(userid);
				
				if(k1bests != 0 && 
						(sportsDataRecordInfo.getK1() == null || k1bests < sportsDataRecordInfo.getK1().getValue())) {
					createSportsDataRecord(userid, st.getId(), "k1");
				}
				
				if (k5bests != 0 && 
						(sportsDataRecordInfo.getK5() == null || k5bests < sportsDataRecordInfo.getK5().getValue())) {
					createSportsDataRecord(userid, st.getId(), "k5");
				}
				
				if (k10bests != 0 && 
						(sportsDataRecordInfo.getK10() == null || k10bests < sportsDataRecordInfo.getK10().getValue())) {
					createSportsDataRecord(userid, st.getId(), "k10");
				}
				
				if (halfbests != 0 && 
						(sportsDataRecordInfo.getHalf() == null || halfbests < sportsDataRecordInfo.getHalf().getValue())) {
					createSportsDataRecord(userid, st.getId(), "half");
				}
				
				if (marathonbests != 0 && 
						(sportsDataRecordInfo.getMarathon() == null || marathonbests < sportsDataRecordInfo.getMarathon().getValue())) {
					createSportsDataRecord(userid, st.getId(), "marathon");
				}
				
				if (sportsDataRecordInfo.getFarthestdistance() == null 
						|| distance > sportsDataRecordInfo.getFarthestdistance().getValue()) {
					createSportsDataRecord(userid, st.getId(), "farthestdistance");
				}
				
				if (sportsDataRecordInfo.getLongesttime() == null
						|| duration > sportsDataRecordInfo.getLongesttime().getValue()) {
					createSportsDataRecord(userid, st.getId(), "longesttime");
				}
			}
			
			return ret > 0?RetCode.OK:RetCode.EXCEPTION;
		}catch(Exception e){
			if( e.getCause() instanceof MySQLIntegrityConstraintViolationException ){
				return RetCode.TRACKDATAEXIST;
			}
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}
	
	private int createSportsDataRecord(Integer userid,Long sportsid,String type) {
		SqlSession session = null;
		int ret = -1;
		
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("sportsid", sportsid);
			params.put("type", type);
			ret = mapper.createSportsDataRecord(params);
			
			logger.info(String.format("添加运动记录, sportsid=%d, type=%s, userid=%d, result=%d",
					sportsid, type, userid, ret));
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		
		return ret;
	}
	
	public List<SportsData> getSportsDataRecordList(Integer userid, String type, Integer from, Integer limit){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("type", type);
			
			if( from!=null )
				params.put("from", from);
			params.put("limit", limit);
	
			return mapper.getSportsDataRecordList(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public SportsDataDetail getSportsDataDetail(Integer userid,Integer dataid){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			params.put("id", dataid);
			return mapper.getSportsDataDetail(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	
	public SportsDataRecordInfo getSportsDataRecordInfo(Integer userid){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			
			SportsDataRecordInfo sportsDataRecordInfo = new SportsDataRecordInfo();

			List<RecordData> recordDataList = mapper.getUserSportsDataRecordData(userid);
			if(recordDataList != null) {
				for(RecordData recordData:recordDataList) {
					if(recordData.getType().equals("1k")) {
						sportsDataRecordInfo.setK1(recordData);
					} else if(recordData.getType().equals("5k")) {
						sportsDataRecordInfo.setK5(recordData);
					} else if(recordData.getType().equals("10k")) {
						sportsDataRecordInfo.setK10(recordData);
					} else if(recordData.getType().equals("half")) {
						sportsDataRecordInfo.setHalf(recordData);
					} else if(recordData.getType().equals("marathon")) {
						sportsDataRecordInfo.setMarathon(recordData);
					} else if(recordData.getType().equals("longesttime")) {
						sportsDataRecordInfo.setLongesttime(recordData);
					} else if(recordData.getType().equals("farthestdistance")) {
						sportsDataRecordInfo.setFarthestdistance(recordData);
					} 
				}
			}
			
			Map<String,Object> summaryMap = mapper.getUserSportsDataSummary(userid);
			if(summaryMap != null) {
				sportsDataRecordInfo.setSumdistance(summaryMap.get("sumdistance") != null ? (Double)summaryMap.get("sumdistance") : 0.0);
				sportsDataRecordInfo.setSumwechatdistance(summaryMap.get("wechatsumdistance") != null ? 
						(Double)summaryMap.get("wechatsumdistance") : 0.0);
				sportsDataRecordInfo.setSumcalories(summaryMap.get("sumcalories") != null ?
						((BigDecimal)summaryMap.get("sumcalories")).intValue() : 0);
				sportsDataRecordInfo.setSumduration(summaryMap.get("sumduration") != null ?
						((BigDecimal)summaryMap.get("sumduration")).intValue() : 0);
			}
		
			return sportsDataRecordInfo;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public List<SportsData> getSportsData(Integer userid,String filter,String sortField ,String order,Integer from,Integer limit ){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			if( StringUtils.isNotBlank(sortField) ){
				params.put("sort", sortField);
				if( StringUtils.isNotBlank(order) ){
					params.put("order", order);
				}
			}
			if( from!=null )
				params.put("from", from);
			params.put("limit", limit);
			if( StringUtils.isNotBlank(filter)){
				String f = parseFilter( filter );
				if( f.length() > 0 ){
					params.put("filter", f);
				}
			}
			return mapper.getSportsData(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public List<SportsData> syncSportsData(Integer userid,String filter,String sortField ,String order,Integer from,Integer limit ){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid", userid);
			if( StringUtils.isNotBlank(sortField) ){
				params.put("sort", sortField);
				if( StringUtils.isNotBlank(order) ){
					params.put("order", order);
				}
			}
			if( from!=null )
				params.put("from", from);
			params.put("limit", limit);
			if( StringUtils.isNotBlank(filter)){
				String f = parseFilter( filter );
				if( f.length() > 0 ){
					params.put("filter", f);
				}
			}
			return mapper.syncSportsData(params);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public RetCode deleteSportsData(Integer userid,Integer dataid){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("dataid",dataid);
			params.put("userid", userid);
			int ret = mapper.deleteSportsData(params);
			if( ret <= 0 ){
				return RetCode.NOT_EXIST;
			}
			return RetCode.OK;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return RetCode.EXCEPTION;
	}
	
	public JSONArray getLatestYearDistanceData(Integer userid,String type,String offset){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid",userid);
			params.put("type", type);
			params.put("offset", offset);
			List<Map<String,Object>> res = mapper.latestYearData(params);
			JSONArray array = new JSONArray();
			for(Map<String,Object> row:res ){
				JSONObject each = new JSONObject(row);
				array.add(each);
			}
			return array;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public JSONArray getRank(Integer userid,
			Integer groupid,
			Integer begin,
			Integer end,
			String rankType,
			Integer iscontacts,
			Integer fromIndex,
			Integer limit){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid",userid);
			params.put("groupid",groupid);
			params.put("beginTime",begin );
			params.put("endTime",end );
			params.put("rankType", rankType);
			params.put("iscontacts", iscontacts);
			params.put("fromIndex", fromIndex);
			params.put("limitValue", limit);
			List<Map<String,Object>> res = mapper.myDistanceRank(params);
			JSONArray array = new JSONArray();
			for(Map<String,Object> row:res ){
				JSONObject each = new JSONObject(row);
				array.add(each);
			}
			return array;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	public JSONArray getDistanceStatistics(Integer userid,String condition,String type){
		SqlSession session = null;
		try{
			session = DBUtils.getSqlSession();
			ActivityMapper mapper = session.getMapper( ActivityMapper.class );
			Map<String,Object> params = new HashMap<String,Object>();
			params.put("userid",userid);
			params.put("queryCondition",condition );
			params.put("type",type );
			List<Map<String,Object>> res = mapper.distanceStatistics(params);
			JSONArray array = new JSONArray();
			for(Map<String,Object> row:res ){
				JSONObject each = new JSONObject(row);
				array.add(each);
			}
			return array;
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( session != null )
				session.close();
		}
		return null;
	}
	
	private String parseFilter(String exp){
		Pattern p = Pattern.compile("(\\w+):(\\S+)");
		Matcher m = p.matcher(exp);
		StringBuilder sb = new StringBuilder();
		while(m.find()){
			String each = m.group();
			String[] pair = each.split(":");
			if( sb.length() > 0 ){
				sb.append( " AND " );
			}
			if(pair[1].startsWith("[")){
				sb.append(pair[0]);
				sb.append(" between ");
				String[] range = pair[1].substring(1,pair[1].lastIndexOf("]")).split(",");
				sb.append( range[0] );
				sb.append( " and " );
				sb.append( range[1] );
			}else{
				sb.append(pair[0]);
				sb.append("=");
				sb.append("'");
				sb.append(pair[1]);
				sb.append("'");
			}
		}
		return sb.toString();
	}
	
}
